#ifndef MACROS_H
#define MACROS_H

#define SAFE(x) do { x } while (0)

#ifdef DEBUG
#  define IF_DEBUG(x) x
#  define DEBUG_CHECK(x, y) if (x) fatal(y)
#  define DEBUG_CHECK1(x, y, a) if (x) fatal(y, a)
#  define DEBUG_CHECK2(x, y, a, b) if (x) fatal(y, a, b)
#else
#  define IF_DEBUG(x)
#  define DEBUG_CHECK(x, y)
#  define DEBUG_CHECK1(x, y, a)
#  define DEBUG_CHECK2(x, y, a, b)
#endif

#define ALLOCATE(type) ((type *)malloc(sizeof(type)))
#define CALLOCATE(num, type) ((type *)malloc(sizeof(type[1]) * (num)))
#define RESIZE(ptr, num, type) ((type *)realloc((void *)ptr, sizeof(type) * (num)))


#define COPY2(x, y)      ((char *)(x))[0] = ((char *)(y))[0]; \
                         ((char *)(x))[1] = ((char *)(y))[1]
#define STORE2(x, y)     *x++ = ((char *)(&(y)))[0]; \
                         *x++ = ((char *)(&(y)))[1]

#define STORE4(x, y)     *x++ = ((char *)(&(y)))[0]; \
                         *x++ = ((char *)(&(y)))[1]; \
                         *x++ = ((char *)(&(y)))[2]; \
                         *x++ = ((char *)(&(y)))[3]

#define COPY_SHORT(x, y) COPY2(x,y)
#define STORE_SHORT(x, y) STORE2(x,y)
#define STORE_INT(x, y) STORE4(x,y)
#define STORE_FLOAT(x, y) STORE4(x,y)
#endif
